import axios from 'axios';
import _ from 'lodash';
import qs from 'qs';
import repeatRequestHandler from './interceptors/repeat-request-handler';
import reponseHandler from './interceptors/response-handler';
import errorHandler from './interceptors/error-handler';
import loadingHandler from './interceptors/loading-handler';
import baseConfig from '../../config/axios';

const instance = axios.create(baseConfig());

//重复请求问题
repeatRequestHandler(instance);

// 请求错误判断
reponseHandler(instance);

// 添加 handleDefaultError 配置项
// 是否默认错误处理
errorHandler(instance);

// 添加 handleDefaultError 配置项
loadingHandler(instance);

export default instance;

// 包装request 函数
export function wrapRequest(apis) {
  const genAxiosRequest = (apiObj, prefixKey) => {
    const result = {};

    Object.keys(apiObj).forEach(key => {
      // isDir仅作为标识
      if (key === 'isDir') {
        return;
      }

      // 如果是多级目录，一级一级处理
      if (apiObj.isDir) {
        result[key] = genAxiosRequest(apiObj[key], prefixKey ? `${prefixKey}.${key}` : key);
        return;
      }

      let currentApi = apiObj[key];

      if (typeof currentApi === 'string') {
        currentApi = {
          url: currentApi,
        };
      }

      // 添加 apikey
      currentApi._apiKey = prefixKey ? `${prefixKey}.${key}` : key;

      result[key] = (params = {}, config = {}) => {
        config = _.merge({}, baseConfig(), currentApi, config);

        // 动态 url params 里匹配参数
        if (config.url.indexOf('/:') > -1) {
          config.url = config.url.replace(/:([^/]+)/, (match, p1) => {
            return params[p1];
          });
        }

        // data body
        if (['post', 'put', 'patch'].indexOf(config.method) > -1) {
          config.data = Object.assign(config.data || Array.isArray(params) ? [] : {}, params);
          // form url 格式
          if (config.headers['Content-Type'] === 'application/x-www-form-urlencoded') {
            config.data = qs.stringify(config.data);
          }

          // FormData 形式
          if (config.headers['Content-Type'] === 'multipart/form-data') {
            config.transformRequest = [
              function(data) {
                const formData = new FormData();

                Object.keys(data).forEach(dataKey => {
                  formData.append(key, data[dataKey]);
                });

                return formData;
              },
            ];
          }
        } else {
          config.params = Object.assign(config.params || {}, params);
        }

        return instance(config).then(response => response.data);
      };
    });

    return result;
  };
  return genAxiosRequest(apis);
}
